using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using CodRevit.ViewModels;
using OfficeOpenXml;
using System.Diagnostics;

namespace CodRevit.Handlers
{
    public class ExportScheduleHandler : IExternalEventHandler
    {
        private readonly UIApplication _uiApp;
        private List<ViewSchedule> _selectedSchedules = new();
        private string _exportPath = string.Empty;
        private ExportScheduleViewModel? _viewModel;

        public ExportScheduleHandler(UIApplication uiApp)
        {
            _uiApp = uiApp;
        }

        public void SetParameters(List<ViewSchedule> selectedSchedules, string exportPath, ExportScheduleViewModel viewModel)
        {
            _selectedSchedules = selectedSchedules;
            _exportPath = exportPath;
            _viewModel = viewModel;
        }

        public void Execute(UIApplication app)
        {
            var exportedSchedules = new List<string>();
            var doc = app.ActiveUIDocument.Document;

            try
            {
                System.Diagnostics.Debug.WriteLine($"[ExportScheduleHandler] 开始导出，总共 {_selectedSchedules.Count} 个明细表");

                // 验证输入参数
                if (!_selectedSchedules.Any())
                {
                    _viewModel?.OnExportFailed("没有选择要导出的明细表");
                    return;
                }

                if (string.IsNullOrEmpty(_exportPath))
                {
                    _viewModel?.OnExportFailed("导出路径无效");
                    return;
                }

                // 设置EPPlus许可证上下文
                ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

                // 创建Excel文件
                using (var package = new ExcelPackage())
                {
                    foreach (var schedule in _selectedSchedules)
                    {
                        try
                        {
                            System.Diagnostics.Debug.WriteLine($"[ExportScheduleHandler] 开始导出明细表: {schedule.Name}");

                            // 创建工作表
                            var worksheet = package.Workbook.Worksheets.Add(SanitizeSheetName(schedule.Name));

                            // 导出明细表数据
                            ExportScheduleToWorksheet(schedule, worksheet);

                            exportedSchedules.Add(schedule.Name);
                            System.Diagnostics.Debug.WriteLine($"[ExportScheduleHandler] 明细表 {schedule.Name} 导出成功");
                        }
                        catch (Exception ex)
                        {
                            System.Diagnostics.Debug.WriteLine($"[ExportScheduleHandler] 导出明细表 {schedule.Name} 时出错: {ex.Message}");
                            // 继续处理其他明细表，不中断整个流程
                        }
                    }

                    // 保存Excel文件
                    var fileInfo = new FileInfo(_exportPath);
                    package.SaveAs(fileInfo);
                }

                // 通知ViewModel导出完成
                if (_viewModel != null)
                {
                    var message = exportedSchedules.Any()
                        ? $"成功导出了 {exportedSchedules.Count} 个明细表到 Excel"
                        : "没有明细表被成功导出";
                    System.Diagnostics.Debug.WriteLine($"[ExportScheduleHandler] 导出完成: {message}");
                    _viewModel.OnExportCompleted(exportedSchedules, message, _exportPath);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"[ExportScheduleHandler] 总体异常: {ex.Message}\n堆栈: {ex.StackTrace}");
                _viewModel?.OnExportFailed(ex.Message);
            }
        }

        private void ExportScheduleToWorksheet(ViewSchedule schedule, ExcelWorksheet worksheet)
        {
            var tableData = schedule.GetTableData();
            var sectionData = tableData.GetSectionData(SectionType.Body);

            int rowCount = sectionData.NumberOfRows;
            int colCount = sectionData.NumberOfColumns;

            // 导出表头
            if (rowCount > 0)
            {
                for (int col = 0; col < colCount; col++)
                {
                    try
                    {
                        var cellText = schedule.GetCellText(SectionType.Header, 0, col);
                        worksheet.Cells[1, col + 1].Value = cellText;
                        worksheet.Cells[1, col + 1].Style.Font.Bold = true;
                    }
                    catch
                    {
                        // 如果获取表头失败，使用默认列名
                        worksheet.Cells[1, col + 1].Value = $"列{col + 1}";
                        worksheet.Cells[1, col + 1].Style.Font.Bold = true;
                    }
                }
            }

            // 导出数据行
            for (int row = 0; row < rowCount; row++)
            {
                for (int col = 0; col < colCount; col++)
                {
                    try
                    {
                        var cellText = schedule.GetCellText(SectionType.Body, row, col);
                        worksheet.Cells[row + 2, col + 1].Value = cellText; // +2 因为第一行是表头
                    }
                    catch
                    {
                        // 如果获取单元格数据失败，留空
                        worksheet.Cells[row + 2, col + 1].Value = "";
                    }
                }
            }

            // 自动调整列宽
            worksheet.Cells.AutoFitColumns();
        }

        private string SanitizeSheetName(string name)
        {
            // Excel工作表名称不能包含某些字符
            var invalidChars = new char[] { '\\', '/', '*', '?', ':', '[', ']' };
            var sanitized = name;
            
            foreach (var c in invalidChars)
            {
                sanitized = sanitized.Replace(c, '_');
            }

            // Excel工作表名称最大长度为31个字符
            if (sanitized.Length > 31)
            {
                sanitized = sanitized.Substring(0, 31);
            }

            return sanitized;
        }

        public string GetName()
        {
            return "ExportScheduleHandler";
        }
    }
}